import React, { useEffect, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { connect, useIntl, history } from 'umi';
import {
  getDetail,
  editDataSet,
  getAnnotInfo,
  getVersionListAPI,
  downloadDataSet,
  releaseDataSet,
  deleteDataSet,
} from '../service';
import { message, Space } from 'antd';
import { showDownloadModal } from '@/utils/utils';
import BasicInfo from './components/BasicInfo';
import EditBasicInfo from './components/EditBasicInfo';
import AnnotInfo from './components/AnnotInfo';
import VersionList from './components/VersionList';

import type { ConnectProps, Dispatch } from 'umi';
import type { StateType, DataType } from '../model';
import type { DetailsType } from './components/BasicInfo';
import type { SubmitType } from './components/EditBasicInfo';
import type { InfoType } from './components/AnnotInfo';
import type { VersionType, OperateType } from './components/VersionList';

interface DetailProps extends ConnectProps {
  dataSet: {
    dataTypes: DataType[];
    sourceType: DataType[];
    annotStatus: DataType[];
  };
  dispatch: Dispatch;
}

const DataSetDetail: React.FC<DetailProps> = props => {
  const { formatMessage: f } = useIntl();
  const {
    dispatch,
    dataSet: {
      dataTypes,
      sourceType,
      annotStatus,
    },
    match,
  } = props;
  const { id: dataSetId } = match?.params as { id: string };
  const versionListAPI = getVersionListAPI(dataSetId);

  const [details, setDetails] = useState<DetailsType>({});
  const [detailLoading, setDetailLoading] = useState<boolean>(false);
  const [visible, setVisible] = useState({ editBasicInfo: false });
  const [loading, setLoading] = useState({ editBasicInfo: false });
  const [annotInfoLoading, setAnnotInfoLoading] = useState<boolean>(false);
  const [annotInfo, setAnnotInfo] = useState<InfoType>({});

  const fetchDetail = async () => {
    setDetailLoading(true);
    try {
      const res = await getDetail(dataSetId);
      setDetailLoading(false);
      if (res && res.code === 0) {
        setDetails(res.data);
      }
    } catch (err) {
      setDetailLoading(false);
      console.log(err);
    }
  };

  useEffect(() => {
    if (!dataTypes.length) {
      dispatch({ type: 'dataSet/getDataType' });
    }
    if (!sourceType.length) {
      dispatch({ type: 'dataSet/getMetaData' });
    }
    fetchDetail();
  }, []);

  const fetchAnnotInfo = async (id: string | number) => {
    setAnnotInfoLoading(true);
    try {
      const res = await getAnnotInfo(id);
      setAnnotInfoLoading(false);
      if (res && res.code === 0) {
        const labeledNum = res.data?.labelProportion
          ?.map((i: { number: number }) => i.number)
          ?.reduce((a: number, b: number) => a + b);
        setAnnotInfo({
          ...res.data,
          labelProportion: res.data?.labelProportion?.concat({
            label: f({ id: 'global.unlabeld' }),
            number: res.data?.totalNum - (labeledNum || 0),
          })
        });
      }
    } catch (err) {
      setAnnotInfoLoading(false);
      console.log(err);
    }
  };

  const onEditBasicInfoClick = () => {
    setVisible({ ...visible, editBasicInfo: true });
  };

  const onEditBasicInfoSubmit = async (values: SubmitType) => {
    setLoading({ ...loading, editBasicInfo: true });
    try {
      const res = await editDataSet(dataSetId, values);
      setLoading({ ...loading, editBasicInfo: false });
      if (res && res.code === 0) {
        message.success(f({ id: 'global.operation.success' }));
        setVisible({ ...visible, editBasicInfo: false });
        fetchDetail();
      }
    } catch (err) {
      console.log(err);
      setLoading({ ...loading, editBasicInfo: false });
    }
  };

  const onOperationClick = async (record: VersionType, type: OperateType, callback?: () => void) => {
    const hide = message.loading(f({ id: `global.${type === 'delete' ? 'delete.' : ''}loading` }));
    let res;
    switch (type) {
      case 'view':
        hide();
        history.push(`/dataManage/dataSet/files/${record.id}`);
        break;
      case 'edit':
        hide();
        history.push(`/dataManage/dataSet/files/${record.id}`);
        break;
      case 'download':
        try {
          res = await downloadDataSet(record.id);
          hide();
          if (res && res.code === 0) {
            showDownloadModal(res.data.downloadLink);
          }
        } catch (err) {
          console.log(err);
          hide();
        }
        break;
      case 'release':
        try {
          res = await releaseDataSet(record.id);
          hide();
          if (res && res.code === 0) {
            message.success(`${f({ id: 'global.release' })}${f({ id: 'global.success' })}`);
            if (callback) callback();
          }
        } catch (err) {
          console.log(err);
          hide();
        }
        break;
      case 'delete':
        try {
          res = await deleteDataSet(record.id);
          hide();
          if (res && res.code === 0) {
            message.success(f({ id: 'global.delete.success' }));
            if (callback) callback();
          }
        } catch (err) {
          console.log(err);
          hide();
        }
        break;
    }
  };

  return (
    <PageHeaderWrapper onBack={() => history.push(`/dataManage/dataSet/list?fromDetail=true`)}>
      <Space direction='vertical' size='large' style={{ width: '100%' }}>
        <BasicInfo
          details={details}
          loading={detailLoading}
          dataTypes={dataTypes}
          sourceType={sourceType}
          onEditBasicInfoClick={onEditBasicInfoClick}
        />
        {details.platformAnnot && details.versionIds && details.versionIds.length > 0 &&
          <AnnotInfo
            info={annotInfo}
            versionIds={details.versionIds}
            loading={annotInfoLoading}
            fetchAnnotInfo={fetchAnnotInfo}
            annotStatus={annotStatus}
          />
        }
        <VersionList
          listAPI={versionListAPI}
          sourceType={sourceType}
          onOperationClick={onOperationClick}
        />
      </Space>
      <EditBasicInfo
        visible={visible.editBasicInfo}
        cancel={() => setVisible({ ...visible, editBasicInfo: false })}
        loading={loading.editBasicInfo}
        curRecord={details}
        onSubmit={onEditBasicInfoSubmit}
      />
    </PageHeaderWrapper>
  )
}

export default connect(({ dataSet }: { dataSet: StateType }) => ({
  dataSet,
}))(DataSetDetail);